package com.bringspring.workflow.engine.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.database.model.DataSourceModel;
import com.bringspring.common.database.util.DbTypeUtil;
import com.bringspring.common.util.DateUtil;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.PageUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.base.exception.WorkFlowException;
import com.bringspring.system.permission.entity.UserRelationEntity;
import com.bringspring.workflow.engine.entity.FlowDelegateEntity;
import com.bringspring.workflow.engine.entity.FlowTaskCirculateEntity;
import com.bringspring.workflow.engine.entity.FlowTaskEntity;
import com.bringspring.workflow.engine.entity.FlowTaskNodeEntity;
import com.bringspring.workflow.engine.entity.FlowTaskOperatorEntity;
import com.bringspring.workflow.engine.entity.FlowTaskOperatorRecordEntity;
import com.bringspring.workflow.engine.enums.FlowTaskStatusEnum;
import com.bringspring.workflow.engine.mapper.FlowTaskMapper;
import com.bringspring.workflow.engine.model.flowbefore.FlowBatchModel;
import com.bringspring.workflow.engine.model.flowtask.FlowTaskListModel;
import com.bringspring.workflow.engine.model.flowtask.PaginationFlowTask;
import com.bringspring.workflow.engine.service.FlowDelegateService;
import com.bringspring.workflow.engine.service.FlowTaskCirculateService;
import com.bringspring.workflow.engine.service.FlowTaskNodeService;
import com.bringspring.workflow.engine.service.FlowTaskOperatorRecordService;
import com.bringspring.workflow.engine.service.FlowTaskOperatorService;
import com.bringspring.workflow.engine.service.FlowTaskService;
import com.bringspring.workflow.engine.util.FlowNature;
import com.bringspring.workflow.engine.util.ServiceAllUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * 流程任务
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月27日 上午9:18
 */
@Slf4j
@Service
public class FlowTaskServiceImpl extends ServiceImpl<FlowTaskMapper, FlowTaskEntity> implements FlowTaskService {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private ServiceAllUtil serviceUtil;
    @Autowired
    private FlowDelegateService flowDelegateService;
    @Autowired
    private FlowTaskNodeService flowTaskNodeService;
    @Autowired
    private FlowTaskOperatorService flowTaskOperatorService;
    @Autowired
    private FlowTaskOperatorRecordService flowTaskOperatorRecordService;
    @Autowired
    private FlowTaskCirculateService flowTaskCirculateService;
    @Autowired
    private DataSourceModel dataSourceModel;

    @Override
    public List<FlowTaskEntity> getMonitorList(PaginationFlowTask paginationFlowTask) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(FlowTaskEntity::getId).gt(FlowTaskEntity::getStatus, FlowTaskStatusEnum.Draft.getCode());
        //关键字（流程名称、流程编码）
        String keyWord = paginationFlowTask.getKeyword() != null ? paginationFlowTask.getKeyword() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(keyWord)) {
            flag = true;
            queryWrapper.lambda().and(
                    t -> t.like(FlowTaskEntity::getEnCode, keyWord)
                            .or().like(FlowTaskEntity::getFullName, keyWord)
            );
        }
        //日期范围（近7天、近1月、近3月、自定义）
        String startTime = paginationFlowTask.getStartTime() != null ? paginationFlowTask.getStartTime() : null;
        String endTime = paginationFlowTask.getEndTime() != null ? paginationFlowTask.getEndTime() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(startTime) && !org.apache.commons.lang3.StringUtils.isEmpty(endTime)) {
            flag = true;
            Date startTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00");
            Date endTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59");
            queryWrapper.lambda().ge(FlowTaskEntity::getCreatorTime, startTimes).le(FlowTaskEntity::getCreatorTime, endTimes);
        }
        //流程状态
        if (ObjectUtil.isNotNull(paginationFlowTask.getStatus())) {
            flag = true;
            queryWrapper.lambda().eq(FlowTaskEntity::getStatus, paginationFlowTask.getStatus());
        }
        //所属流程
        String flowId = paginationFlowTask.getFlowId() != null ? paginationFlowTask.getFlowId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowId)) {
            flag = true;
            queryWrapper.lambda().eq(FlowTaskEntity::getFlowId, flowId);
        }
        //所属分类
        String flowCategory = paginationFlowTask.getFlowCategory() != null ? paginationFlowTask.getFlowCategory() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowCategory)) {
            flag = true;
            queryWrapper.lambda().eq(FlowTaskEntity::getFlowCategory, flowCategory);
        }
        //发起人员
        String creatorUserId = paginationFlowTask.getCreatorUserId() != null ? paginationFlowTask.getCreatorUserId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(creatorUserId)) {
            flag = true;
            queryWrapper.lambda().eq(FlowTaskEntity::getCreatorUserId, creatorUserId);
        }
        //排序
//        if ("desc".equals(paginationFlowTask.getSort().toLowerCase())) {
//            queryWrapper.lambda().orderByDesc(FlowTaskEntity::getCreatorTime);
//        } else {
            queryWrapper.lambda().orderByAsc(FlowTaskEntity::getSortCode).orderByDesc(FlowTaskEntity::getCreatorTime);
//        }
        if (flag) {
            queryWrapper.lambda().orderByDesc(FlowTaskEntity::getLastModifyTime);
        }
        Page<FlowTaskEntity> page = new Page<>(paginationFlowTask.getCurrentPage(), paginationFlowTask.getPageSize());
        IPage<FlowTaskEntity> flowTaskEntityPage = this.page(page, queryWrapper);
        if(!flowTaskEntityPage.getRecords().isEmpty()){
            List<String> ids = flowTaskEntityPage.getRecords().stream().map(m->m.getId()).collect(Collectors.toList());
            queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(FlowTaskEntity::getId, ids);
            //排序
            queryWrapper.lambda().orderByAsc(FlowTaskEntity::getSortCode).orderByDesc(FlowTaskEntity::getCreatorTime);
            if (flag) {
                queryWrapper.lambda().orderByDesc(FlowTaskEntity::getLastModifyTime);
            }
            flowTaskEntityPage.setRecords(this.list(queryWrapper));
        }
        return paginationFlowTask.setData(flowTaskEntityPage.getRecords(), page.getTotal());
    }

    @Override
    public List<FlowTaskEntity> getLaunchList(PaginationFlowTask paginationFlowTask) {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        String userId = userProvider.get().getUserId();
        if (paginationFlowTask.getIsAll() == null || paginationFlowTask.getIsAll() ==0)
            queryWrapper.lambda().select(FlowTaskEntity::getId).eq(FlowTaskEntity::getCreatorUserId, userId);
        queryWrapper.lambda().select(FlowTaskEntity::getId).eq(FlowTaskEntity::getCreatorUserId, userId);
        //关键字（流程名称、流程编码）
        String keyWord = paginationFlowTask.getKeyword() != null ? paginationFlowTask.getKeyword() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(keyWord)) {
            queryWrapper.lambda().and(
                    t -> t.like(FlowTaskEntity::getEnCode, keyWord)
                            .or().like(FlowTaskEntity::getFullName, keyWord)
            );
        }
        if (CollectionUtil.isNotEmpty(paginationFlowTask.getProcessIdList())){
            queryWrapper.lambda().in(FlowTaskEntity::getProcessId,paginationFlowTask.getProcessIdList());
        }
        //日期范围（近7天、近1月、近3月、自定义）
        String startTime = paginationFlowTask.getStartTime() != null ? paginationFlowTask.getStartTime() : null;
        String endTime = paginationFlowTask.getEndTime() != null ? paginationFlowTask.getEndTime() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(startTime) && !org.apache.commons.lang3.StringUtils.isEmpty(endTime)) {
            Date startTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00");
            Date endTimes = DateUtil.stringToDate(DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59");
            queryWrapper.lambda().ge(FlowTaskEntity::getCreatorTime, startTimes).le(FlowTaskEntity::getCreatorTime, endTimes);
        }
        //所属流程
        String flowName = paginationFlowTask.getFlowId() != null ? paginationFlowTask.getFlowId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowName)) {
            queryWrapper.lambda().eq(FlowTaskEntity::getFlowId, flowName);
        }
        //流程状态
        if (ObjectUtil.isNotNull(paginationFlowTask.getStatus())) {
            queryWrapper.lambda().eq(FlowTaskEntity::getStatus, paginationFlowTask.getStatus());
        }
        //所属分类
        String flowCategory = paginationFlowTask.getFlowCategory() != null ? paginationFlowTask.getFlowCategory() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowCategory)) {
            queryWrapper.lambda().eq(FlowTaskEntity::getFlowCategory, flowCategory);
        }
        //排序
        if ("asc".equals(paginationFlowTask.getSort().toLowerCase())) {
            queryWrapper.lambda().orderByAsc(FlowTaskEntity::getStatus).orderByAsc(FlowTaskEntity::getStartTime);
        } else {
            queryWrapper.lambda().orderByDesc(FlowTaskEntity::getLastModifyTime).orderByDesc(FlowTaskEntity::getStartTime).orderByAsc(FlowTaskEntity::getStatus);
        }
        Page<FlowTaskEntity> page = new Page<>(paginationFlowTask.getCurrentPage(), paginationFlowTask.getPageSize());
        IPage<FlowTaskEntity> flowTaskEntityPage = this.page(page, queryWrapper);
        if(!flowTaskEntityPage.getRecords().isEmpty()){
            List<String> ids = flowTaskEntityPage.getRecords().stream().map(m->m.getId()).collect(Collectors.toList());
            queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(FlowTaskEntity::getId, ids);
            //排序
            if ("asc".equals(paginationFlowTask.getSort().toLowerCase())) {
                queryWrapper.lambda().orderByAsc(FlowTaskEntity::getLastModifyTime).orderByAsc(FlowTaskEntity::getStartTime).orderByAsc(FlowTaskEntity::getStatus);
            } else {
                queryWrapper.lambda().orderByDesc(FlowTaskEntity::getLastModifyTime).orderByDesc(FlowTaskEntity::getStartTime).orderByAsc(FlowTaskEntity::getStatus);
            }
            flowTaskEntityPage.setRecords(this.list(queryWrapper));
        }
        return paginationFlowTask.setData(flowTaskEntityPage.getRecords(), page.getTotal());
    }



    @Override
    public List<FlowTaskListModel> getWaitList(PaginationFlowTask paginationFlowTask) {
        List<FlowTaskListModel> result = getWaitListAll(paginationFlowTask);
        //返回数据
        return paginationFlowTask.setData(PageUtil.getListPage((int) paginationFlowTask.getCurrentPage(), (int) paginationFlowTask.getPageSize(), result), result.size());
    }

    @Override
    public List<FlowTaskListModel> getBatchWaitList(PaginationFlowTask paginationFlowTask) {
        paginationFlowTask.setIsBatch(1);
        List<FlowTaskListModel> result = getWaitListAll(paginationFlowTask);
        //返回数据
        return paginationFlowTask.setData(PageUtil.getListPage((int) paginationFlowTask.getCurrentPage(), (int) paginationFlowTask.getPageSize(), result), result.size());
    }

    @Override
    public List<FlowTaskListModel> getWaitListAll(PaginationFlowTask paginationFlowTask) {
        String userId = userProvider.get().getUserId();
        StringBuilder dbSql = new StringBuilder();
        //查询自己的待办
        dbSql.append(" AND (");
        //委托审核
        StringJoiner joiner = new StringJoiner(",");
        joiner.add("'" + userId + "'");
        List<FlowDelegateEntity> flowDelegateList = flowDelegateService.getUser(userId);
        for (FlowDelegateEntity delegateEntity : flowDelegateList) {
            joiner.add("'" + delegateEntity.getCreatorUserId() + "'");
        }
        dbSql.append("o.HANDLE_ID in (" + joiner.toString() + " ) )");
        //关键字（流程名称、流程编码）
        String keyWord = paginationFlowTask.getKeyword() != null ? paginationFlowTask.getKeyword() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(keyWord)) {
            dbSql.append(" AND (t.ENCODE like '%" + keyWord + "%' or t.FULL_NAME like '%" + keyWord + "%') ");
        }
        //日期范围（近7天、近1月、近3月、自定义）
        String startTime = paginationFlowTask.getStartTime() != null ? paginationFlowTask.getStartTime() : null;
        String endTime = paginationFlowTask.getEndTime() != null ? paginationFlowTask.getEndTime() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(startTime) && !org.apache.commons.lang3.StringUtils.isEmpty(endTime)) {
            if (DbTypeUtil.checkOracle(dataSourceModel)) {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND o.CREATOR_TIME Between TO_DATE('" + startTimes + "','yyyy-mm-dd HH24:mi:ss') AND TO_DATE('" + endTimes + "','yyyy-mm-dd HH24:mi:ss') ");
            } else {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND o.CREATOR_TIME Between '" + startTimes + "' AND '" + endTimes + "' ");
            }
        }
        //所属流程
        String flowId = paginationFlowTask.getFlowId() != null ? paginationFlowTask.getFlowId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowId)) {
            dbSql.append(" AND t.FLOW_ID = '" + flowId + "'");
        }
        //所属分类
        String flowCategory = paginationFlowTask.getFlowCategory() != null ? paginationFlowTask.getFlowCategory() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowCategory)) {
            dbSql.append(" AND t.FLOW_CATEGORY = '" + flowCategory + "'");
        }
        //发起人员
        String creatorUserId = paginationFlowTask.getCreatorUserId() != null ? paginationFlowTask.getCreatorUserId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(creatorUserId)) {
            dbSql.append(" AND t.CREATOR_USER_ID = '" + creatorUserId + "'");
        }
        //节点编码
        String nodeCode = paginationFlowTask.getNodeCode() != null ? paginationFlowTask.getNodeCode() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(nodeCode)) {
            dbSql.append(" AND o.Node_Code = '" + nodeCode + "'");
        }
        //是否批量
        Integer isBatch = paginationFlowTask.getIsBatch() != null ? paginationFlowTask.getIsBatch() : null;
        if (!ObjectUtil.isEmpty(isBatch)) {
            dbSql.append(" AND t.IS_BATCH = " + isBatch + " ");
        }
        //排序
        StringBuilder orderBy = new StringBuilder();
        if ("desc".equals(paginationFlowTask.getSort().toLowerCase())) {
            orderBy.append(" Order by CREATOR_TIME DESC");
        } else {
            orderBy.append(" Order by CREATOR_TIME ASC");
        }
        String sql = dbSql.toString() + " " + orderBy.toString();
        List<FlowTaskListModel> data = this.baseMapper.getWaitList(sql);
        List<FlowTaskListModel> result = new LinkedList<>();
        for (FlowTaskListModel entity : data) {
            List<Date> list = StringUtils.isNotEmpty(entity.getDescription()) ? JsonUtil.getJsonToList(entity.getDescription(), Date.class) : new ArrayList<>();
            boolean delegate = true;
            boolean isuser = entity.getHandleId().equals(userId);
            entity.setFullName(!isuser ? entity.getFullName() + "(委托)" : entity.getFullName());
            List<FlowDelegateEntity> flowList = flowDelegateList.stream().filter(t -> t.getFlowId().equals(entity.getFlowId())).collect(Collectors.toList());
            //判断是否有自己审核
            if (!isuser) {
                //是否委托当前流程引擎 true是 flas否
                delegate = flowList.stream().filter(t -> t.getCreatorUserId().equals(entity.getHandleId())).count() > 0;
            }
            if (delegate) {
                result.add(entity);
                Date date = new Date();
                boolean del = list.stream().filter(t -> t.getTime() > date.getTime()).count() > 0;
                if (del) {
                    result.remove(entity);
                }
            }
        }
        return result;
    }

    @Override
    public List<FlowTaskListModel> getTrialList(PaginationFlowTask paginationFlowTask) {
        String userId = userProvider.get().getUserId();
        Map<String, Object> queryParam = new HashMap<>(16);
        StringBuilder dbSql = new StringBuilder();
        //关键字（流程名称、流程编码）
        String keyWord = paginationFlowTask.getKeyword() != null ? paginationFlowTask.getKeyword() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(keyWord)) {
            dbSql.append(" AND (t.ENCODE like '%" + keyWord + "%' or t.Full_Name like '%" + keyWord + "%') ");
        }
        //日期范围（近7天、近1月、近3月、自定义）
        String startTime = paginationFlowTask.getStartTime() != null ? paginationFlowTask.getStartTime() : null;
        String endTime = paginationFlowTask.getEndTime() != null ? paginationFlowTask.getEndTime() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(startTime) && !org.apache.commons.lang3.StringUtils.isEmpty(endTime)) {
            if (DbTypeUtil.checkOracle(dataSourceModel)) {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND t.F_CreatorTime Between TO_DATE('" + startTimes + "','yyyy-mm-dd HH24:mi:ss') AND TO_DATE('" + endTimes + "','yyyy-mm-dd HH24:mi:ss') ");
            } else {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND t.F_CreatorTime Between '" + startTimes + "' AND '" + endTimes + "' ");
            }
        }
        //所属流程
        String flowId = paginationFlowTask.getFlowId() != null ? paginationFlowTask.getFlowId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowId)) {
            dbSql.append(" AND t.FLOW_ID = '" + flowId + "' ");
        }
        //所属分类
        String flowCategory = paginationFlowTask.getFlowCategory() != null ? paginationFlowTask.getFlowCategory() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowCategory)) {
            dbSql.append(" AND t.FLOW_CATEGORY = '" + flowCategory + "' ");
        }
        //发起人员
        String creatorUserId = paginationFlowTask.getCreatorUserId() != null ? paginationFlowTask.getCreatorUserId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(creatorUserId)) {
            dbSql.append(" AND t.CREATOR_USER_ID = '" + creatorUserId + "' ");
        }
        dbSql.append(" Order by t.Creator_Time DESC ");
        queryParam.put("handleId", userId);
        queryParam.put("sql", dbSql.toString());
        List<FlowTaskListModel> data = this.baseMapper.getTrialList(queryParam);
        return paginationFlowTask.setData(PageUtil.getListPage((int) paginationFlowTask.getCurrentPage(), (int) paginationFlowTask.getPageSize(), data), data.size());
    }

    @Override
    public List<FlowTaskListModel> getTrialList() {
        String userId = userProvider.get().getUserId();
        Map<String, Object> queryParam = new HashMap<>(16);
        StringBuilder dbSql = new StringBuilder();
        queryParam.put("handleId", userId);
        queryParam.put("sql", dbSql.toString());
        List<FlowTaskListModel> data = this.baseMapper.getTrialList(queryParam);
        return data;
    }

    @Override
    public List<FlowTaskEntity> getWaitList() {
        String userId = userProvider.get().getUserId();
        StringBuilder dbSql = new StringBuilder();
        //查询自己的待办
        dbSql.append(" AND (");
        dbSql.append("o.Handle_Id = '" + userId + "' ");
        //委托审核
        List<FlowDelegateEntity> flowDelegateList = flowDelegateService.getUser(userId);
        if (flowDelegateList.size() > 0) {
            dbSql.append(" OR ");
            for (int i = 0; i < flowDelegateList.size(); i++) {
                FlowDelegateEntity delegateEntity = flowDelegateList.get(i);
                //委托的人
                dbSql.append(" o.Handle_Id = '" + delegateEntity.getCreatorUserId() + "' ");
                if (flowDelegateList.size() - 1 > i) {
                    dbSql.append(" OR ");
                }
            }
            dbSql.append(")");
        } else {
            dbSql.append(")");
        }
        List<FlowTaskListModel> data = this.baseMapper.getWaitList(dbSql.toString());
        //返回数据
        List<FlowTaskEntity> result = JsonUtil.getJsonToList(data, FlowTaskEntity.class);
        return result;
    }

    @Override
    public List<FlowTaskEntity> getDashboardWaitList() {
        String userId = userProvider.get().getUserId();
        StringBuilder dbSql = new StringBuilder();
        //查询自己的待办
        dbSql.append(" AND (");
        dbSql.append("o.Handle_Id = '" + userId + "' ");
        //委托审核
        List<FlowDelegateEntity> flowDelegateList = flowDelegateService.getUser(userId);
        if (flowDelegateList.size() > 0) {
            dbSql.append(" OR ");
            for (int i = 0; i < flowDelegateList.size(); i++) {
                FlowDelegateEntity delegateEntity = flowDelegateList.get(i);
                //委托的人
                dbSql.append(" o.Handle_Id = '" + delegateEntity.getCreatorUserId() + "' ");
                if (flowDelegateList.size() - 1 > i) {
                    dbSql.append(" OR ");
                }
            }
            dbSql.append(")");
        } else {
            dbSql.append(")");
        }
        List<FlowTaskListModel> data = this.baseMapper.getWaitList(dbSql.toString());
        //返回数据
        List<FlowTaskEntity> result = JsonUtil.getJsonToList(data, FlowTaskEntity.class);
        return result;
    }

    @Override
    public List<FlowTaskEntity> getAllWaitList() {
        String userId = userProvider.get().getUserId();
        StringBuilder dbSql = new StringBuilder();
        //查询自己的待办
        dbSql.append(" AND (");
        dbSql.append("o.Handle_Id = '" + userId + "' )  Order by CREATOR_TIME DESC");
        List<FlowTaskListModel> data = this.baseMapper.getWaitList(dbSql.toString());
        List<FlowTaskEntity> result = JsonUtil.getJsonToList(data, FlowTaskEntity.class);
        return result;
    }

    @Override
    public List<FlowTaskListModel> getCirculateList(PaginationFlowTask paginationFlowTask) {
        String userId = userProvider.get().getUserId();
        List<String> userIdList = new ArrayList<>();
        userIdList.add(userId);
        List<UserRelationEntity> list = serviceUtil.getListByUserIdAll(userIdList);
        List<String> userRelationList = list.stream().map(u -> u.getObjectId()).collect(Collectors.toList());
        String[] objectId = (String.join(",", userRelationList) + "," + userId).split(",");
        //传阅人员
        StringBuilder dbSql = new StringBuilder();
        dbSql.append(" AND (");
        for (int i = 0; i < objectId.length; i++) {
            dbSql.append("c.OBJECT_ID = '" + objectId[i] + "'");
            if (objectId.length - 1 > i) {
                dbSql.append(" OR ");
            }
        }
        dbSql.append(")");
        //关键字（流程名称、流程编码）
        String keyWord = paginationFlowTask.getKeyword() != null ? paginationFlowTask.getKeyword() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(keyWord)) {
            dbSql.append(" AND (t.ENCODE like " + " '%" + keyWord + "%' " + " or t.FULL_NAME like" + " '%" + keyWord + "%') ");
        }
        //日期范围（近7天、近1月、近3月、自定义）
        String startTime = paginationFlowTask.getStartTime() != null ? paginationFlowTask.getStartTime() : null;
        String endTime = paginationFlowTask.getEndTime() != null ? paginationFlowTask.getEndTime() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(startTime) && !org.apache.commons.lang3.StringUtils.isEmpty(endTime)) {
            if (DbTypeUtil.checkOracle(dataSourceModel)) {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND c.CREATOR_TIME Between TO_DATE('" + startTimes + "','yyyy-mm-dd HH24:mi:ss') AND TO_DATE('" + endTimes + "','yyyy-mm-dd HH24:mi:ss') ");
            } else {
                String startTimes = DateUtil.daFormatYmd(Long.parseLong(startTime)) + " 00:00:00";
                String endTimes = DateUtil.daFormatYmd(Long.parseLong(endTime)) + " 23:59:59";
                dbSql.append(" AND c.CREATOR_TIME Between  '" + startTimes + "' AND '" + endTimes + "' ");
            }
        }
        //所属流程
        String flowId = paginationFlowTask.getFlowId() != null ? paginationFlowTask.getFlowId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowId)) {
            dbSql.append(" AND t.FLOW_ID = '" + flowId + "'");
        }
        //所属分类
        String flowCategory = paginationFlowTask.getFlowCategory() != null ? paginationFlowTask.getFlowCategory() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(flowCategory)) {
            dbSql.append(" AND t.FLOW_CATEGORY = '" + flowCategory + "'");
        }
        //发起人员
        String creatorUserId = paginationFlowTask.getCreatorUserId() != null ? paginationFlowTask.getCreatorUserId() : null;
        if (!org.apache.commons.lang3.StringUtils.isEmpty(creatorUserId)) {
            dbSql.append(" AND t.CREATOR_USER_ID = '" + creatorUserId + "'");
        }
        //排序
        if ("desc".equals(paginationFlowTask.getSort().toLowerCase())) {
            dbSql.append(" Order by CREATOR_TIME DESC");
        } else {
            dbSql.append(" Order by CREATOR_TIME DESC");
        }
        List<FlowTaskListModel> data = this.baseMapper.getCirculateList(dbSql.toString());
        return paginationFlowTask.setData(PageUtil.getListPage((int) paginationFlowTask.getCurrentPage(), (int) paginationFlowTask.getPageSize(), data), data.size());
    }

    @Override
    public FlowTaskEntity getInfo(String id) throws WorkFlowException {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTaskEntity::getId, id);
        FlowTaskEntity entity = this.getOne(queryWrapper);
        if (entity == null) {
            throw new WorkFlowException(MsgCode.WF115.get());
        }
        return entity;
    }

    @Override
    public FlowTaskEntity getDraftTaskByProcessId(String processId) throws WorkFlowException {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTaskEntity::getProcessId, processId).orderByDesc(FlowTaskEntity::getId);
        List<FlowTaskEntity> list = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            return list.get(0);
        }else {
            return null;
        }
    }
    @Override
    public void update(FlowTaskEntity entity) {
        this.updateById(entity);
    }

    @Override
    public void create(FlowTaskEntity entity) {
        this.save(entity);
    }

    @Override
    public FlowTaskEntity getInfoSubmit(String id, SFunction<FlowTaskEntity, ?>... columns) {
        List<FlowTaskEntity> list = getInfosSubmit(new String[]{id}, columns);
        if(list.isEmpty()){
            return null;
        }
        return list.get(0);
    }

    @Override
    public List<FlowTaskEntity> getInfosSubmit(String[] ids, SFunction<FlowTaskEntity, ?>... columns) {
        List<FlowTaskEntity> resultList = Collections.emptyList();
        if(ids == null || ids.length == 0){
            return resultList;
        }
        LambdaQueryWrapper<FlowTaskEntity> queryWrapper = new LambdaQueryWrapper<>();
        if(ids.length == 1){
            queryWrapper.select(columns).and(
                    t -> t.eq(FlowTaskEntity::getId, ids[0])
            );
            resultList = this.list(queryWrapper);
            if(resultList.isEmpty()){
                queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.select(columns).and(
                        t -> t.eq(FlowTaskEntity::getProcessId, ids[0])
                );
                resultList = this.list(queryWrapper);
            }
        }else{
            queryWrapper.select(FlowTaskEntity::getId).and(t->{
                t.in(FlowTaskEntity::getId, ids).or().in(FlowTaskEntity::getProcessId, ids);
            });
            List<String> resultIds = this.listObjs(queryWrapper, t->t.toString());
            if(!resultIds.isEmpty()) {
                queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.select(columns).in(FlowTaskEntity::getId, resultIds);
                resultList = this.list(queryWrapper);
            }
        }
        return resultList;
    }

    @Override
    public void delete(FlowTaskEntity entity) throws WorkFlowException {
        //只能删除0、3、4状态任务(0-等待提交|3-审核驳回|4审核撤销)
        if (!checkStatus(entity.getStatus())) {
            throw new WorkFlowException(MsgCode.WF116.get());
        } else {
            List<String> idList = new ArrayList() {{
                add(entity.getId());
            }};
            this.deleteAll(idList, true, true);
        }
    }

    @Override
    public void deleteChild(FlowTaskEntity entity) {
        List<FlowTaskEntity> flowTaskList = getChildList(entity.getId(), FlowTaskEntity::getId);
        List<String> idList = flowTaskList.stream().map(FlowTaskEntity::getId).collect(Collectors.toList());
        this.deleteAll(idList, true, true);
    }

    @Override
    public void delete(String[] ids) throws WorkFlowException {
        if (ids.length > 0) {
            List<FlowTaskEntity> flowTaskList = getOrderStaList(Arrays.asList(ids));
            boolean isDel = flowTaskList.stream().filter(t -> t.getFlowType() == 1).count() > 0;
            if (isDel) {
                throw new WorkFlowException(MsgCode.WF117.get());
            }
            isDel = flowTaskList.stream().filter(t -> !FlowNature.ParentId.equals(t.getParentId()) && StringUtils.isNotEmpty(t.getParentId())).count() > 0;
            if (isDel) {
                throw new WorkFlowException(MsgCode.WF118.get());
            }
            List<String> idList = Arrays.asList(ids);
            this.deleteAll(idList, true, true);
        }
    }

    @Override
    public List<FlowTaskEntity> getTaskList(String id, SFunction<FlowTaskEntity, ?>... columns) {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTaskEntity::getFlowId, id);
        queryWrapper.lambda().select(columns);
        return this.list(queryWrapper);
    }

    @Override
    public List<FlowTaskEntity> getOrderStaList(List<String> id) {
        List<FlowTaskEntity> list = new ArrayList<>();
        if (id.size() > 0) {
            QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(FlowTaskEntity::getId, id);
            list = this.list(queryWrapper);
        }
        return list;
    }

    @Override
    public List<FlowTaskEntity> getChildList(String id, SFunction<FlowTaskEntity, ?>... columns) {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(columns).in(FlowTaskEntity::getParentId, id);
        return this.list(queryWrapper);
    }

    @Override
    public List<FlowTaskEntity> getTaskFlowList(String flowId) {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTaskEntity::getFlowId, flowId);
        List<Integer> list = new ArrayList() {{
            add(2);
            add(5);
        }};
        queryWrapper.lambda().notIn(FlowTaskEntity::getStatus, list);
        queryWrapper.lambda().eq(FlowTaskEntity::getIsBatch, 1);
        queryWrapper.lambda().select(FlowTaskEntity::getId);
        return this.list(queryWrapper);
    }

    @Override
    public List<FlowTaskEntity> getFlowList(String flowId) {
        QueryWrapper<FlowTaskEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FlowTaskEntity::getFlowId, flowId);
        queryWrapper.lambda().select(FlowTaskEntity::getId);
        return list(queryWrapper);
    }

    @Override
    public List<FlowBatchModel> batchFlowSelector() {
        List<FlowTaskOperatorEntity> operatorList = flowTaskOperatorService.getBatchList();
        List<String> taskIdList = operatorList.stream().map(FlowTaskOperatorEntity::getTaskId).collect(Collectors.toList());
        List<FlowTaskEntity> taskList = getOrderStaList(taskIdList);
        Map<String, List<FlowTaskEntity>> flowIdList = taskList.stream().filter(t -> ObjectUtil.isNotEmpty(t.getIsBatch()) && t.getIsBatch() == 1).collect(Collectors.groupingBy(FlowTaskEntity::getFlowId));
        List<FlowBatchModel> batchFlowList = new ArrayList<>();
        for (String key : flowIdList.keySet()) {
            List<FlowTaskEntity> flowTaskList = flowIdList.get(key);
            List<String> flowTask = flowTaskList.stream().map(FlowTaskEntity::getId).collect(Collectors.toList());
            if (flowTaskList.size() > 0) {
                String flowName = flowTaskList.stream().map(FlowTaskEntity::getFlowName).distinct().collect(Collectors.joining(","));
                String flowId = flowTaskList.stream().map(FlowTaskEntity::getFlowId).distinct().collect(Collectors.joining(","));
                Long count = operatorList.stream().filter(t -> flowTask.contains(t.getTaskId())).count();
                FlowBatchModel batchModel = new FlowBatchModel();
                batchModel.setNum(count);
                batchModel.setId(flowId);
                batchModel.setFullName(flowName + "(" + count + ")");
                batchFlowList.add(batchModel);
            }
        }
        batchFlowList = batchFlowList.stream().sorted(Comparator.comparing(FlowBatchModel::getNum).reversed()).collect(Collectors.toList());
        return batchFlowList;
    }

    /**
     * 验证有效状态
     * @param status 状态编码 (0-等待提交|3-审核驳回|4审核撤销)
     * @return true
     */
    private boolean checkStatus(int status) {
        if (status == FlowTaskStatusEnum.Draft.getCode() || status == FlowTaskStatusEnum.Reject.getCode()
                || status == FlowTaskStatusEnum.Revoke.getCode()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 递归删除所有子节点
     *
     * @param idList
     * @param isRecord
     * @param isCirculate
     */
    private void deleteAll(List<String> idList, boolean isRecord, boolean isCirculate) {
        List<String> idAll = new ArrayList<>();
        this.deleTaskAll(idList, idAll);
        if (idAll.size() > 0) {
            QueryWrapper<FlowTaskEntity> task = new QueryWrapper<>();
            task.lambda().in(FlowTaskEntity::getId, idAll);
            this.remove(task);
            QueryWrapper<FlowTaskNodeEntity> node = new QueryWrapper<>();
            node.lambda().in(FlowTaskNodeEntity::getTaskId, idAll);
            flowTaskNodeService.remove(node);
            QueryWrapper<FlowTaskOperatorEntity> operator = new QueryWrapper<>();
            operator.lambda().in(FlowTaskOperatorEntity::getTaskId, idAll);
            flowTaskOperatorService.remove(operator);
            if (isRecord) {
                QueryWrapper<FlowTaskOperatorRecordEntity> record = new QueryWrapper<>();
                record.lambda().in(FlowTaskOperatorRecordEntity::getTaskId, idAll);
                flowTaskOperatorRecordService.remove(record);
            }
            if (isCirculate) {
                QueryWrapper<FlowTaskCirculateEntity> circulate = new QueryWrapper<>();
                circulate.lambda().in(FlowTaskCirculateEntity::getTaskId, idAll);
                flowTaskCirculateService.remove(circulate);
            }
        }
    }

    /**
     * 获取子节点下所有数据
     *
     * @param idAll
     * @param idList
     */
    private void deleTaskAll(List<String> idList, List<String> idAll) {
        idAll.addAll(idList);
        for (String id : idList) {
            List<FlowTaskEntity> taskAll = this.getChildList(id, FlowTaskEntity::getId);
            List<String> list = taskAll.stream().map(FlowTaskEntity::getId).collect(Collectors.toList());
            this.deleTaskAll(list, idAll);
        }
    }

}
